#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>

#define TASK_NUM 10

//定义函数指针
typedef void(*task_t)();
task_t tasks[TASK_NUM];

void task1(){
    printf("这是一个执行打印日志的任务，pid: %d\n",getpid());
}

void task2(){
    printf("这是一个执行检测网络健康状态的一个任务,pid: %d\n",getpid());
}

void task3(){
    printf("这是一个进行绘制图形化界面的任务,pid: %d\n",getpid());
}

int AddTask(task_t t);

void InitTask(){
    int i=0;
    for(;i<TASK_NUM;i++){
        tasks[i]=NULL;
    }
    AddTask(task1);
    AddTask(task2);
    AddTask(task3);
}

int AddTask(task_t t){
     int pos=0;
     for(;pos<TASK_NUM;pos++){
         if(!tasks[pos]){
             break;
         }
     }
     if(pos==TASK_NUM){
         return -1;
     }
     tasks[pos]=t;
     return 0;
}

void ExecuteTask(){
    int i=0;
    for(;i<TASK_NUM;i++){
        if(!tasks[i]){
            continue;
        }
        tasks[i]();
    }
}

//非阻塞轮询测试
int main(){
    //创建子进程
    pid_t id=fork();
    if(id<0){
        perror("fork");
        return 1;
    }
    else if(id==0){
        //子进程
        int cnt=5;
        while(cnt){
            printf("I am a childprocess, pid: %d, ppid: %d, cnt: %d\n",getpid(),getppid(),cnt);
            cnt--;
            sleep(1);
        }
        exit(0);
    }
    else{
        InitTask();
        int status=0;
        //父进非阻塞轮询等待子进程
        while(1){
            pid_t ret=waitpid(id,&status,WNOHANG);
            if(ret>0){
                if(WIFEXITED(status)){
                    printf("子进程正常跑完，退出码：%d\n",WEXITSTATUS(status));
                }
                else{
                    printf("子进程出现异常\n");
                }
                //结束循环
                break;
            }
            else if(ret<0){
                printf("wait failed!\n");
                //结束循环
                break;
            }
            else{
                //ret=0
                //printf("子进程还没有结束，继续等待\n");
                //sleep(1);
                
                ExecuteTask();
                usleep(500000);
            }
        }
        
    }
    sleep(3);


    return 0;
}


//多个子进程测试
#define N 10
void runchild(){
    int cnt=5;
    while(cnt){
        printf("I am a child process,pid: %d,ppid: %d\n",getpid(),getppid());         
        sleep(1);
        cnt--;
    }
}
//int main(){
//    int i=0;
//    for(;i<N;i++){
//        pid_t id=fork();
//        if(id==0){
//            runchild();
//            exit(i);
//        }
//        //这句话只有父进程才会执行
//        printf("create child process: %d success\n",id);
//    }
//    
//    //sleep(10);
//
//    //等待
//    for(i=0;i<N;i++){
//        //wait当任意一个子进程退出时，wait回收子进程
//        //如果任意一个子进程都不退出呢？
//        //pid_t ret=wait(NULL);
//        
//        int status=0;
//        pid_t ret=waitpid(-1,&status,0);
//        if(ret>0){
//            printf("wait %d success,exit code: %d\n",ret,WEXITSTATUS(status));
//        }
//    }
//
//    sleep(5);
//
//
//    return 0;
//}



//单个子进程的进程等待测试
//int main(){
//    pid_t id=fork();
//
//    if(id<0){
//        perror("fork");
//        return 1;
//    }
//    else if(id==0){
//        //子进程
//        int cnt=5;
//        while(cnt){
//            printf("I am a child, pid:%d, ppid:%d, cnt: %d\n",getpid(),getppid(),cnt);
//            sleep(1);
//            cnt--;
//        }
//
//        //子进程测试异常信号
//        //int a=10;
//        //a/=0;
//
//        exit(1);
//        
//    }
//    else{
//        //父进程
//        int cnt=10;
//        while(cnt){
//            printf("I am a parent, pid:%d, ppid:%d, cnt: %d\n",getpid(),getppid(),cnt);
//            sleep(1);
//            cnt--;
//        }
//
//        //父进程回收
//        //wait等待成功时，返回子进程的pid
//        //目前为止，进程等待是必须的！
//        //wait是等待任意一个子进程退出
//        
//        int status=0;
//        pid_t ret=waitpid(id,&status,0);
//        if(ret==id){
//            //waitpid获取子进程的退出信息
//            //printf("wait success, ret: %d, status: %d\n",ret,status);
//            
//            //分别获取退出信息中的异常信号和退出码
//            //printf("wait success, ret: %d, exit sig: %d, exit code: %d\n",ret,status&0x7F,(status>>8)&0xFF);
//            
//
//            if(WIFEXITED(status)){
//                printf("进程是正常跑完的，退出码：%d\n",WEXITSTATUS(status));
//            }
//            else{
//                printf("进程出现异常");
//            }
//        }
//        //父进程系统调用失败
//        else{
//            printf("wait failed!\n");
//        }
//
//        sleep(5);
//
//    }
//
//
//    return 0;
//}
